#!/usr/bin/env python
# -*- coding: utf-8 -*- 

#Kiwi Bot
#Make by @nge1nCorsic4 in 2010
#Modified by @nge1nCorsic4 in 2011


#This program is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 2 of the License, or
#(at your option) any later version.

#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.

#You should have received a copy of the GNU General Public License along
#with this program; if not, write to the Free Software Foundation, Inc.,
#51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import kiwi, kiwi.plugin, kiwi.events, kiwi.config, kiwi.lang, random, threading, time

class teams(kiwi.plugin.Plugin):
	def onStart(self):
		self.lang = kiwi.lang.Lang(self,'teams')
		ServNumber = kiwi.config.configuration().kiwi.kiwidir
		self.config = kiwi.config.configuration('@kiwi/conf/'+ServNumber+'/teams.cfg')
		self.kickspec = kiwi.getPath(self.config.settings.auto_kickspectators)
		self.timekick = kiwi.getPath(self.config.settings.timekick)
		self.friend = int(self.config.settings.friendslevel)
		self.registerEvent(kiwi.events.EVT_GAME_START, self.GameStart)
		self.registerEvent(kiwi.events.EVT_GAME_SCORE, self.ctf_score)
		self.registerEvent(kiwi.events.EVT_CLIENT_ITEM, self.ctf_flag)
		self.registerEvent(kiwi.events.EVT_CLIENT_KILL, self.teamkill)
		self.registerEvent(kiwi.events.EVT_GAME_SURVIVORWINNER, self.ts_score)
		self.registerEvent(kiwi.events.EVT_CLIENT_DISCONNECT, self.client_deco)
		if self.kickspec == 'on':
			self.registerEvent(kiwi.events.EVT_CLIENT_UPDATE, self.kick_spec)
		self.register = self.main.getPlugin('admin').mod.registerCommand
		self.register('teams', int(self.config.levels.teams), self._teams, "000900")
		self.register('shuffle', int(self.config.levels.shuffle), self._shuffle, "000901")
		self.register('fa', int(self.config.levels.fa), self._fa, "000600")
		self.register('fp', int(self.config.levels.fp), self._fp, "000601")
		self.dicTK = {}
		self.SpecKick = {}
		self.init_team()
	def onStop(self):
		self.main.getPlugin('admin').mod.deleteCommand('teams')
		self.main.getPlugin('admin').mod.deleteCommand('shuffle')
		self.main.getPlugin('admin').mod.deleteCommand('fa')
		self.main.getPlugin('admin').mod.deleteCommand('fp')
	def GameStart(self, event):
		self.init_team()
		self.regulTeam()
	def init_team(self):
		self.clientFlag  = []
		self.Teams = False
		self.redScore = 0
		self.blueScore = 0
	def ctf_score(self, event):
		flag = event.flag.rstrip(":")
		if flag == '2':
			self.clientFlag = []
			if event.team_flag == 'team_CTF_blueflag':
				self.blueScore += 1
			else:
				self.redScore += 1
			self.regulTeam()
		elif flag == '0' :
			if event.id in self.clientFlag :
				self.clientFlag.remove(event.id)
	def ctf_flag(self, event):
		if event.item == "team_CTF_redflag" or event.item =="team_CTF_blueflag" :
			if not event.id in self.clientFlag :
				self.clientFlag.append(event.id)
	def ts_score(self, event):
		if event.team == 'Red':
			self.redScore += 1
		elif event.team == 'Blue':
			self.blueScore += 1
		self.regulTeam()
	def client_deco(self, event):
		if self.kickspec == 'on':
			if self.SpecKick.has_key(event.id):
				del self.SpecKick[event.id]
		dic = self.dicTK
		for d in dic:
			list =  dic[d]
			while event.id in list:
				list.remove(event.id)
			dic[d] = list
		if dic.has_key(event.id):
			del dic[event.id]
		self.Teams = True
	def kick_spec(self, event):
		if self.SpecKick.has_key(event.id):
			if len(self.clients.getClientsList()) > 8 :
				client = self.clients.getClientById(event.id)[0]
				if client.rights < self.friend :
					if int(client.team) == 3 :
						if self.SpecKick[client.id] == 1:
							self.SpecKick[client.id] = 2
							threading.Timer(int(self.timekick), self.kick_spec, (event,)).start()
							self.output.tell(client.id,self.lang.lang(event,'00956')%self.timekick)
						elif self.SpecKick[client.id] == 2:
							threading.Timer(60, self.kick, (client,)).start()
							self.output.tell(client.id,self.lang.lang(event,'00957'))
					else:
						self.SpecKick[client.id] = 1
		else:
			self.SpecKick[event.id] = 1
	def kick(self, client):
		try :
			if client.team == '3':
				self.output.send('kick %s' %client.id)
				self.output.send('^1%s ^3%s.'%(client.name,self.lang.lang('','00958')))
			else:
				self.output.tell(client.id,self.lang.lang(client,'00959'))
				self.SpecKick[client.id] = 1
		except Exception:
			pass
	def checkTKteam(self,killer,dead):
		red,blue,spec = self.clients.getTeams()
		nb = 0
		for client in red:
			if client.id == killer:
				nb+=1
			elif client.id == dead:
				nb+=1
		if nb != 1:
			return True
		return False
	def teamkill(self, event):
		dead, killer, vars = event.dead, event.killer, event.vars
		if dead != killer :
			if killer != 1022:
				noRespond = (	'MOD_FALLING',
								'MOD_SLIME',
								'MOD_CRUSH',
								'MOD_TARGET_LASER',
								'MOD_WATER',
								'MOD_LAVA',
								'MOD_TRIGGER_HURT',
								'UT_MOD_FLAG')
				if not vars[-1] in noRespond :
					C_killer = self.clients.getClientById(killer)
					if C_killer:
						if C_killer[0].rights < self.friend:
							if self.checkTKteam(killer,dead):
								C_dead = self.clients.getClientById(dead)[0]
								self.output.tell(dead,self.lang.lang(C_dead,"00601")%C_killer[0].name)
								dic = self.dicTK
								if dic.has_key(dead):
									list = dic[dead]
									list.append(killer)
									dic[dead] = list
									nb = 0
									for a in dic:
										for b in dic[a] :
											if killer == b:
												nb += 1
									if nb == 3:
										self.output.tell(killer,self.lang.lang(C_killer[0],"00602"))
									elif nb > 3:
										self.output.send('kick %s'%killer)
										self.output.say('^1%s ^4%s.'%(C_killer[0].name,self.lang.lang(C_killer[0],"00603")))
								else:
									dic[dead]=[killer]
		self.regulDeath(event)
	def checkTeam(self):
		red,blue,spec = self.clients.getTeams()
		min, minS, max, maxS = red,'red', blue,'blue'
		if len(red) > len(blue):
			min, minS, max, maxS = blue, 'blue', red, 'red'
		if abs(len(max) - len(min)) < 2:
			if abs(len(max) - len(min)) == 1:
				if self.checkScore():
					self.regulScore(min,max,minS)
			return False
		else:
			return min,max,minS
	def checkScore(self):
		if abs(self.blueScore - self.redScore) > 3 :
			return True
		return False
	def checkTeamScore(self):
		if self.blueScore > self.redScore :
			return 'blue'
		else:
			return 'red'
	def checkClient(self,max):
		list_max = []
		for client in max:
			if client.rights  == 0 :
				list_max.append(client)
		if len(list_max) > 0:
			client = random.choice(list_max)
		else:
			client = random.choice(max)
		return client
	def regulScore(self,min,max,minS):
		if minS != self.checkTeamScore() :
			client = self.checkClient(max)
			if not client.id in self.clientFlag :
				self.output.send('forceteam %s %s'%(client.id, minS))
				self.output.bigtext('^4%s'%self.lang.lang('','00952'))
				self.Teams = False
	def regulTeam(self):
		if self.checkTeam():
			min,max,minS = self.checkTeam()
			while abs(len(min) - len(max)) > 1:
				client = self.checkClient(max)
				if not client.id in self.clientFlag :
					self.output.send('forceteam %s %s'%(client.id, minS))
					max.remove(client)
					min.append(client)
					self.output.bigtext('^4%s'%self.lang.lang('','00952'))
					self.Teams = False
	def regulDeath(self,event):
		if self.Teams:
			if self.checkTeam():
				min,max,minS = self.checkTeam()
				for client in max:
					if client.id == event.dead :
						self.output.send('forceteam %s %s'%(event.dead, minS))
						self.output.bigtext('^4%s'%self.lang.lang('','00952'))
			self.Teams = False
	def _teams(self, event):
		if self.Teams :
			self.output.tell(event.id, self.lang.lang(event,'00968'))
		else:
			self.Teams = True
			self.output.tell(event.id, self.lang.lang(event,'00969'))
	def _shuffle(self, event):
		self.output.send('shuffleteams')
	def _fa(self, event):
		dic, dead = self.dicTK, event.id
		if dic.has_key(dead):
			if len(dic[dead]) >= 2 :
				dic[dead] = []
				self.output.tell(dead,self.lang.lang(event,"00606"))
	def _fp(self, event):
		dic, dead = self.dicTK, event.id
		client = self.main.clients.getClientById
		if dic.has_key(dead):
			if len(dic[dead]) >= 2 :
				id = dic[dead][-1]
				dic[dead] = dic[dead][:-1]
				self.output.tell(id,'%s ^4%s'%(client(dead)[0].name,self.lang.lang(client(id)[0],"00604")))
				self.output.tell(dead,self.lang.lang(event,"00605")%client(id)[0].name)